/**
 * gis store
 * manage all states of gis
 * @author
 */
import {
  Module,
  Mutation,
  VuexModule,
  getModule,
  Action,
} from 'vuex-module-decorators'
import store from '@/store'
import {
  queryTabsByProjectIdApi,
  addTabByProjectIdApi,
  deleteTabByIdApi,
  queryLayersByTabIdApi,
  getAllGisDataApi,
  addLayerApi,
  deleteLayerByIdApi,
  plotLayerByGeoJsonApi,
  resetSeenApi,
  renameLayerApi,
  saveCentroidLayerApi,
  saveBufferLayersApi,
  resetOrderApi,
  searchAdministrativeApi,
  queryTableDetailApi,
  getNumericalColApi,
  getNumericalResponseApi,
  modifyTabApi,
  copyTabApi,
  nearSearchApi,
  queryQueryStatApi,
  pointToLineApi,
  saveInfoApi,
  synchronousTabApi,
  querySynchronousStatus,
  plotLayerBySliceGeoJsonApi,
} from '@/api/gis'
import { message } from 'ant-design-vue'
import { cloneDeep, isFunction } from 'lodash'
import SelectionType from '@/util/selection-type'
import { Compare } from '@/util/data-view-table-helper'

export interface IKeyValue {
  [key: string]: any
}

export interface Tab {
  tabId: number
  tabName: string
  projectId?: number
  userId?: number
  data?: any
}

export interface Layer {
  id: number
  name: string
  type?: string
  visible?: boolean
  order?: boolean
  viewName?: string
}

// 图层数据
export interface LayerData {
  datajson: any
  geojson: any
  type: string
}

// 图层数据 map
export interface LayersData {
  [key: number]: LayerData | null
}

export interface IColumn {
  name: string
  type: number
  desc?: string
  semantic?: string
  _stamp?: number
  width?: number
}

/**
 * 单元格信息
 */
export interface CellInfo {
  rowIndex: number
  columnName: string
  _record_id_: string
  cellValue: string
}

export interface TableVueInstance {
  clearAllSelect(): void
  clearTableSlection: void
  checkHeight(): void
}

export interface SelectionInfo {
  // 起始索引
  startIndex: number
  // 结束索引
  endIndex: number
  // 是否符合以XXX开头的条件
  isStartWith: boolean
  // 是否符合以XXX结尾的条件
  isEndWidth: boolean
  // 是否符合单词位置推荐的条件（前后有空格），这里位置指的是单词位置
  isWordPos: boolean
  // 单词位置
  wordPos: number
  // 是否符合选中位置一样的规则,这里位置指的是索引位置
  isSelectionPos: boolean
  // 是否符合以xx单词开头的规则，刷选内容在最前面且后面有空格
  isStartWithWord: boolean
  // 前置单词
  startWithWord: string
  // 是否符合以xx单词结尾的规则，刷选内容在最后面且前面有空格
  isEndWithWord: boolean
  // 后置单词
  endWithWord: string
  // 真实行号
  _record_id_: string
  // 显示行号
  rowIndex: number
  // 列名
  columnName: string
  // 选中的字符
  selection: string
  // 是否为刷选多个的情况
  isMultiple?: boolean
  // 多选模式下 刷选内容是否都一样
  isSameSelection?: boolean
  // 多选模式下 刷选内容位置是否都一样
  isSamePos?: boolean
  // 所选模式下所有选中信息
  multipleSelectionInfo?: { [key: string]: SelectionInfo }
  // 多选模式下行索引集合
  rowIndexArray?: Array<number>
  // 多选模式下行号集合
  _record_id_Array?: Array<string>
  // 当前列类型
  columnDesc?: string
  // 当前完整值
  fullValue?: any
}

/**
 * 图层默认信息
 * @param layer
 */
function layerDefaultData(layer: any): any {
  const defaultData: any = {
    tagInfo: {
      globalInfo: {
        featureType:
          layer.type === 'circle'
            ? 'circle'
            : layer.type === 'line'
            ? 'solid-line'
            : 'pure-color-polygon', // 点： 实心点，三角形， 正方形，线： 实线， 虚线， 面： 纯色面
        globalOpacity: 1, // 要素透明度
        globalColor:
          layer.type === 'circle'
            ? '#ff0000'
            : layer.type === 'line'
            ? '#345678'
            : '#467be8', // 全局颜色
        paint: {}, // 全局绘制参数
      },
      // 属性标记
      attributeTag: [],
    },
  }
  if (layer.type === 'line') {
    defaultData.tagInfo.globalInfo.paint['line-dasharray'] = [1] // 默认实线
  }
  return defaultData
}

@Module({ dynamic: true, namespaced: true, name: 'GisStore', store })
class GisStore extends VuexModule {
  private _projectId: number | null = null
  private _gisTabs: Tab[] = [] // 所有画布
  private _currentTabId: number | null = null // 当前画布 tab Id
  // 图层列表
  private _layerList: any[] = [] // 当前tab 图层 列表
  // 图层数据 id: geoJson
  private _layerData: LayersData = {}
  // 测量方式
  private _mode: any = null
  // 当选单选的图层
  private _selectLayer: any = null
  // 地图各类 loading 状态
  public _mapLoading: boolean = false
  // 新生成的图层 (分析生成的图层信息)
  public _analysisCreateLayer: Layer | null = null
  public _fitBoundsAfterCreateNewLayer: boolean = true // 生成新图层后是否定位
  private _updateLayerDataAfterGenerateNewField: any = null // 在图层生成的字段后需要更新图层数据
  private _needUpdateTime: number | null = null // 需要更新图层数据的时间戳

  private _mapboxInstance: any = null // mapbox 实例

  private _oldTabInfo: any = null // 上一个地图的信息， 用来作为切换对比

  public get oldTabInfo() {
    return this._oldTabInfo
  }

  @Mutation
  public setOldTabInfo(tab: any) {
    this._oldTabInfo = tab
  }

  public get mapboxInstance() {
    return this._mapboxInstance
  }

  @Mutation
  public setMapboxInstance(mapBox: any) {
    this._mapboxInstance = mapBox
  }

  public get projectId() {
    return this._projectId
  }

  @Mutation
  public setProjectId(id: number) {
    this._projectId = id
  }

  public get gisTabs() {
    return this._gisTabs
  }

  public get mode() {
    return this._mode
  }

  public get currentTabId() {
    return this._currentTabId
  }

  @Mutation
  public setCurrentTabId(id: number) {
    this._currentTabId = id
  }

  public get layerList() {
    return this._layerList
  }
  public get firstLayerOfList() {
    return this._layerList.length > 0 ? this._layerList[0] : null
  }
  public get selectLayer() {
    return this._selectLayer
  }

  @Mutation
  public setSelectLayer(layer: any) {
    this._selectLayer = layer
  }

  public get layerData() {
    return this._layerData
  }

  public get mapLoading() {
    return this._mapLoading
  }

  @Mutation
  public setMapLoading(loading: boolean) {
    this._mapLoading = loading
  }

  public get analysisCreateLayer() {
    return this._analysisCreateLayer
  }

  @Mutation
  public setAnalysisCreateLayer(layer: any | null) {
    this._analysisCreateLayer = layer
  }
  public get fitBoundsAfterCreateNewLayer() {
    return this._fitBoundsAfterCreateNewLayer
  }

  @Mutation
  public setFitBoundsAfterCreateNewLayer(value: boolean) {
    this._fitBoundsAfterCreateNewLayer = value
  }
  public get updateLayerDataAfterGenerateNewField() {
    return this._updateLayerDataAfterGenerateNewField
  }

  public get needUpdateTime() {
    return this._needUpdateTime
  }

  @Mutation
  public setNeedUpdateLayerAndTime({
    layer,
    time,
  }: {
    layer: any | null
    time: any
  }) {
    this._updateLayerDataAfterGenerateNewField = layer
    this._needUpdateTime = time
  }

  /**
   * 目前图层表字段更新， 需要更新图层数据 （后期更改方式）
   * @param layer
   * @param time
   */
  @Mutation
  public updateCurrentLayerInfo({
    layer,
    time,
  }: {
    layer: any | null
    time: any
  }) {
    this._updateLayerDataAfterGenerateNewField = layer
    this._needUpdateTime = time
    this._selectLayer = layer
    const index: number = this._layerList.findIndex(
      (item: Layer) => item.id === layer.id
    )
    if (index > -1) {
      this._layerList.splice(index, 1, layer)
    }
  }

  /**
   * 清除数据
   */
  @Mutation
  public clearGisInfo() {
    this._gisTabs = []
    this._currentTabId = null
    this._layerList = []
    this._layerData = {}
    this._selectLayer = null
    this._fullScreenState = false
    this._layerPanelState = this._recordPanelAndToolStatus.layerPanelState
    this._gisAnalysisToolState =
      this._recordPanelAndToolStatus.gisAnalysisToolState
    this._mapboxInstance.remove()
  }

  /**
   * ToolBar
   */
  private _currentToolBarAction: any = null // 当前激活的 工具栏
  public get currentToolBarAction() {
    return this._currentToolBarAction
  }
  @Mutation
  public setCurrentToolBarAction(action: any) {
    this._currentToolBarAction = action
  }

  @Mutation
  public setGisTabs(tabs: Tab[]) {
    this._gisTabs = tabs
  }

  @Mutation
  public setMode(mode: any[]) {
    this._mode = mode
  }

  /**
   * 获取当前项目下多有 gis tab
   */
  @Action({ commit: 'setGisTabs' })
  public async queryTabsByProjectId(parameters: any) {
    const response: any = await queryTabsByProjectIdApi({ data: parameters })
    if (response.data.code === 100) {
      return response.data.result.map((tab: any) => {
        return tab
      })
    }
    return []
  }

  /**
   * 创建增加 画布 tab
   */
  @Action
  public async addTabByProjectId(parameters: any) {
    const response = await addTabByProjectIdApi({ data: parameters })
    if (response.data.code === 100) {
      const tab: any = response.data.result
      const afterTabs: Tab[] = [...this._gisTabs, tab]
      this.context.commit('setGisTabs', afterTabs)
    }
    return response
  }

  /**
   * 复制 画布 tab
   */
  @Action
  public async copyTabApiByTabId(parameters: any) {
    const response = await copyTabApi({ data: parameters })
    if (response.data.code === 100) {
      const tab: any = response.data.result
      const afterTabs: Tab[] = [...this._gisTabs, tab]
      this.context.commit('setGisTabs', afterTabs)
    }
    return response
  }

  /**
   * 删除 画布 tab
   */
  @Action
  public async deleteGisTab(parameters: any) {
    const response = await deleteTabByIdApi({ data: parameters })
    const { tabId } = parameters
    if (response.data.code === 100) {
      const deleteIndex: number = this._gisTabs.findIndex(
        (tab: Tab) => tab.tabId === tabId
      )
      this._gisTabs.splice(deleteIndex, 1)
    }
    return response
  }

  /**
   * 修改 画布 tab (name 和设置， 地图)
   */
  @Action
  public async editGisTab(parameters: any) {
    const response = await modifyTabApi({ data: parameters })
    // 有 tabName 是修改名字
    if (response.data.code === 100) {
      message.success('修改成功！')
      this.context.commit('updateTabName', response.data.result)
      this.context.commit('setOldTabInfo', response.data.result)
    } else {
      message.error('修改失败！')
    }
    return response
  }

  @Mutation
  public updateTabName({ tabId, tabName, data }: any) {
    const index: number = this._gisTabs.findIndex(
      (tab: any) => tab.tabId === tabId
    )
    if (index > -1) {
      this._gisTabs[index].tabName = tabName
      this._gisTabs[index].data = {
        ...this._gisTabs[index].data,
        ...data,
      }
    }
  }

  /**
   * 获取 当前用户下所有 gis 数据
   */
  @Action
  public async queryAllGisData() {
    const response: any = await getAllGisDataApi()
    if (response.data.code === 100) {
      return response.data.result
    }
    return []
  }

  /**
   * 载入 gis 数据到 图层管理
   */
  @Action
  public async loadGisDataToLayerManagement(parameters: any) {
    const response: any = await addLayerApi({ data: parameters })
    if (response.data.code === 100) {
      response.data.result = response.data.result.map((item: any) => {
        return {
          ...item,
          data: {
            ...layerDefaultData(item),
            ...item.data,
          },
        }
      })
      this.context.commit('setLayerList', [
        ...response.data.result,
        ...this._layerList,
      ])
    }
    return response
  }

  /**
   * 获取 图层 list
   * @param parameters
   */
  @Action
  public async queryLayersById(parameters: any) {
    const response: any = await queryLayersByTabIdApi({ data: parameters })
    if (response.data.code === 100) {
      // 给图层增加 属性标记
      this.context.commit(
        'setLayerList',
        response.data.result.map((item: any) => {
          return {
            // TODO 图层信息
            ...item,
            data: {
              ...layerDefaultData(item),
              ...item.data,
            },
          }
        })
      )
    }
    return response
  }

  @Mutation
  public setLayerList(layerList: any) {
    this._layerList = layerList.sort(
      (layer1: any, layer2: any) => layer1.order - layer2.order
    )
  }

  @Mutation
  public updateLayerListOrder(parameters: any) {
    const { orders } = parameters
    this._layerList.forEach((layer: any) => {
      layer.order = orders.findIndex((id: any) => id === layer.id)
    })
  }

  /**
   * 删除图层
   * @param parameters
   */
  @Action
  public async deleteLayerById(parameters: any) {
    const response: any = await deleteLayerByIdApi({ data: parameters })
    if (response.data.code === 100) {
      const { layerIds } = parameters
      layerIds.forEach((id: number) => {
        const deleteIndex: number = this.layerList.findIndex(
          (item: any) => item.id === id
        )
        this._layerList.splice(deleteIndex, 1)
      })
    }
    return response
  }

  /**
   * 修改图层名称
   * @param parameters
   */
  @Action
  public async editLayerName(parameters: any) {
    const response: any = await renameLayerApi({ data: parameters })
    if (response.data.code === 100) {
      this.context.commit('updateLayerPropertyKey', {
        id: parameters.layerId,
        property: 'name',
        value: parameters.layerName,
      })
    }
    return response
  }

  /**
   * 修改图层可见状态
   * @param parameters
   */
  @Action
  public async editLayerSeen(parameters: any) {
    const response: any = await resetSeenApi({ data: parameters })
    if (response.data.code === 100) {
      this.context.commit('updateLayerPropertyKey', {
        id: parameters.layerId,
        property: 'visible',
        value: parameters.visible,
      })
    }
    return response
  }

  /**
   * 修改图层可见状态
   * @param parameters
   */
  @Action
  public async resetLayerOrder(parameters: any) {
    const response: any = await resetOrderApi({ data: parameters })
    if (response.data.code === 100) {
      this.context.commit('updateLayerListOrder', parameters)
    }
    return response
  }

  @Mutation
  public updateLayerPropertyKey({ id, property, value }: any) {
    const index: number = this._layerList.findIndex(
      (layer: any) => layer.id === id
    )
    if (index > -1) {
      this._layerList[index][property] = value
    }
  }

  /**
   * 获取 图层数据
   * @param parameters
   * @param tabId
   */
  @Action
  public async queryLayerDataById({
    parameters,
    tabId,
  }: {
    parameters: any
    tabId: any
  }) {
    const response: any = await plotLayerByGeoJsonApi({ data: parameters })
    const isCurrentTab: boolean = tabId === this._currentTabId
    if (response.data.code === 100 && isCurrentTab) {
      const geoData: any = response.data.result
      this.context.commit('addLayerData', { [parameters.layerId]: geoData })
    }
    return response
  }

  /**
   * 分片获取 图层数据
   * @param passFata
   */
  @Action
  public async queryLayerDataBySliceGeoJson(passFata: any) {
    const { layer, projectId } = passFata
    let data: any = null // 数据
    let sliceJsonInfo: any = [] // 分片信息
    let sliceInfo: any = {} // 当前分片信息
    async function sliceQueryGeojson() {
      if (sliceJsonInfo.length > 0) {
        sliceInfo = {
          sliceIndex: sliceJsonInfo[0].index,
          sliceOffset: sliceJsonInfo[0].offset,
          slicePageSize: sliceJsonInfo[0].pageSize,
        }
      }
      const parameters: any = {
        projectId, // 画布id
        layerId: layer.id, // 图层id
        sliceSize: 1024 * 1024 * 4, //	每个数据分片的预估大小(仅第一次请求）
        sliceIndex: 0, //	数据分片索引，即数据的第几个分片
        sliceOffset: 0, //	数据分片偏移
        slicePageSize: 0, //	数据分片长度
        ...sliceInfo,
      }
      const response: any = await plotLayerBySliceGeoJsonApi({
        data: parameters,
      })
      if (response.data.code === 100) {
        const { result } = response.data
        if (result.geojson) {
          // 处理获取到的图层分片数据
          // 存储
          if (data) {
            // @ts-ignore
            data.geojson.features = data.geojson.features.concat(
              result.geojson.features
            )
          } else {
            data = result
          }
        }
        // 代表是第一次请求
        if (result.slicejson) {
          sliceJsonInfo = result.slicejson.slice(1) // 去除第一个已经获取到的数据的分片信息
          if (sliceJsonInfo.length > 0) {
            await sliceQueryGeojson()
          }
        } else {
          sliceJsonInfo.shift() // 删除一个分片信息
          if (sliceJsonInfo.length > 0) {
            await sliceQueryGeojson()
          }
        }
      }
    }
    try {
      await sliceQueryGeojson()
      return data
    } catch (error) {
      console.error(error)
      return null
    }
  }

  /**
   * 分片存储图层数据
   * @param layerDataInfo
   */
  @Mutation
  public addLayerDataBySliceGeoJson({
    layerId,
    geoData,
  }: {
    layerId: number
    geoData: any
  }) {
    if (this._layerData[layerId]) {
      // @ts-ignore
      this._layerData[layerId].geojson.features = this._layerData[
        layerId
      ]?.geojson.features.concat(geoData.geojson.features)
    } else {
      this._layerData[layerId] = geoData
    }
  }

  @Mutation
  public addLayerData(layerDataInfo: LayersData | null) {
    this._layerData = {
      ...this._layerData,
      ...layerDataInfo,
    }
  }

  @Mutation
  public setLayerData(data: any) {
    this._layerData = data
  }

  /**
   * 确定生成几何中心图层(接口返回所有图层)
   * @param parameters
   */
  @Action
  public async saveCentroidLayer(parameters: any) {
    const response: any = await saveCentroidLayerApi({ data: parameters })
    if (response.data.code === 100) {
      let newLayer: any = response.data.result.find(
        (layer: any) => layer.order === 1
      )
      newLayer = {
        ...newLayer,
        data: {
          ...layerDefaultData(newLayer),
          ...newLayer.data,
        },
      }
      this.context.commit('setLayerList', [newLayer, ...this._layerList])
      this.context.commit('setAnalysisCreateLayer', newLayer)
    }
    return response
  }

  /**
   * 确定生成缓冲区图层 (接口返回所有图层)
   * @param parameters
   */
  @Action
  public async saveBufferLayers(parameters: any) {
    const response: any = await saveBufferLayersApi({ data: parameters })
    if (response.data.code === 100) {
      let newLayer: any = response.data.result.find(
        (layer: any) => layer.order === 1
      )
      newLayer = {
        ...newLayer,
        data: {
          ...layerDefaultData(newLayer),
          ...newLayer.data,
        },
      }
      this.context.commit('setLayerList', [newLayer, ...this._layerList])
      this.context.commit('setAnalysisCreateLayer', newLayer)
    }
    return response
  }

  /**
   * 近邻查询 (接口返回所有图层)
   * @param parameters
   */
  @Action
  public async nearSearchSaveLayer(parameters: any) {
    const response: any = await nearSearchApi({ data: parameters })
    if (response.data.code === 100) {
      let newLayer: any = response.data.result.find(
        (layer: any) => layer.order === 1
      )
      newLayer = {
        ...newLayer,
        data: {
          ...layerDefaultData(newLayer),
          ...newLayer.data,
        },
      }
      this.context.commit('setLayerList', [newLayer, ...this._layerList])
      this.context.commit('setAnalysisCreateLayer', newLayer)
    }
    return response
  }

  /**
   * 近邻查询 (接口返回所有图层)
   * @param parameters
   */
  @Action
  public async pointToLineLayer(parameters: any) {
    const response: any = await pointToLineApi({ data: parameters })
    if (response.data.code === 100) {
      let newLayer: any = response.data.result.find(
        (layer: any) => layer.order === 1
      )
      newLayer = {
        ...newLayer,
        data: {
          ...layerDefaultData(newLayer),
          ...newLayer.data,
        },
      }
      this.context.commit('setLayerList', [newLayer, ...this._layerList])
      this.context.commit('setAnalysisCreateLayer', newLayer)
    }
    return response
  }

  /**
   * 调用天地图搜索服务
   * @param parameters
   */
  @Action
  public async searchAdministrative(parameters: any) {
    const response: any = await searchAdministrativeApi({ params: parameters })
    return response
  }

  /**
   * 数理分析 根据属性计算
   */
  @Action
  public async querySelectableAttributesByLayerId(parameters: any) {
    const response: any = await getNumericalColApi({ data: parameters })
    return response
  }

  /**
   * 数理分析 计算
   */
  @Action
  public async getNumericalResponseApiByLayerId(parameters: any) {
    const response: any = await getNumericalResponseApi({ data: parameters })
    return response
  }

  /**
   * 图层管理、属性、标记、及其三部分的开合状态及宽高 分析工具的开合状态
   * @private
   */
  private _layerPanelState: boolean = true // 图层管理 属性 标记  三部分的开合状态
  private _gisAnalysisToolState: boolean = false // 分析工具打开状态
  public get layerPanelState() {
    return this._layerPanelState
  }
  public get gisAnalysisToolState() {
    return this._gisAnalysisToolState
  }
  @Mutation
  public setLayerPanelState(state: boolean) {
    this._layerPanelState = state
  }
  @Mutation
  public setGisAnalysisToolState(state: boolean) {
    this._gisAnalysisToolState = state
  }

  /**
   * 图层数据详情相关 -------- start --------
   */
  private _gisDataHeight: number = 38 // 底部数据详情 总体高度
  private _gisDataWidth: number = 0 // 底部数据详情 总体宽度
  private _viewDataLayer: any = null // 查看数据的图层
  private _layerTableColumns: any = [] // 图层数据表列
  private _layerTableData: any = null // 图层数据表数据
  private _isTableDetailLoading: boolean = false // 数据详情 loading
  private _fullScreenState: boolean = false // 全屏状态
  private _recordPanelAndToolStatus: any = {
    layerPanelState: true, // 图层管理 属性 标记  三部分的开合状态
    gisAnalysisToolState: false, // 分析工具打开状态
  }
  private _viewDataLayerTime: number = 0 // 图层管理 menu 查看图层数据详情使用
  public get gisDataHeight() {
    return this._gisDataHeight
  }
  public get gisDataWidth() {
    return this._gisDataWidth
  }
  public get viewDataLayer() {
    return this._viewDataLayer
  }
  public get layerTableColumns() {
    return this._layerTableColumns
  }
  public get layerTableData() {
    return this._layerTableData
  }
  public get isTableDetailLoading() {
    return this._isTableDetailLoading
  }
  public get fullScreenState() {
    return this._fullScreenState
  }
  public get viewDataLayerTime() {
    return this._viewDataLayerTime
  }
  @Mutation
  public setGisDataHeight(height: number) {
    this._gisDataHeight = height
  }
  @Mutation
  public setGisDataWidth(width: number) {
    this._gisDataWidth = width
  }
  @Mutation
  public setViewDataLayer(layer: any) {
    this._viewDataLayer = layer
  }
  @Mutation
  public setLayerTableData(data: any) {
    if (data.mode !== 'detail') {
      // detail: 只是table detail 发生变化(适用于表格滚动加载或者head不变的情况下进行数据筛选), all: header和detail都变化
      const stamp = +new Date()
      data.head.forEach((item: IKeyValue) => {
        item._stamp = stamp
      })
    }
    this._layerTableColumns = data.head.map((column: any) => {
      if (column.semantic === 'category') {
        return {
          ...column,
          semantic: null,
        }
      }
      return column
    })
    this._layerTableData = data.data
  }
  @Mutation
  public setDataTableDetailLoading(status: boolean) {
    this._isTableDetailLoading = status
  }
  @Mutation
  public setRecordPanelAndToolStatus() {
    this._recordPanelAndToolStatus = {
      layerPanelState: this._layerPanelState,
      gisAnalysisToolState: this._gisAnalysisToolState,
    }
  }
  @Mutation
  public setFullScreen(state: boolean) {
    this._fullScreenState = state

    if (!state) {
      this._layerPanelState = this._recordPanelAndToolStatus.layerPanelState
      this._gisAnalysisToolState =
        this._recordPanelAndToolStatus.gisAnalysisToolState
    }
  }
  @Mutation
  public setViewDataLayerTime() {
    this._viewDataLayerTime = new Date().getTime()
  }

  // 数据详情表翻页使用
  private _tableDataCount: number = 0 // 共有多少数据量
  private _totalPages: number = 0 // 表格数据共多少页
  private _tableCurPage: number = 0 // 当前页码
  private _tableHeight: number = 128 // 底部数据详情表格高度
  public get tableDataCount() {
    return this._tableDataCount
  }
  public get totalPages() {
    return this._totalPages
  }
  public get tableCurPage() {
    return this._tableCurPage
  }
  public get tableHeight() {
    return this._tableHeight
  }
  @Mutation
  public setTotalPages(count: number) {
    this._totalPages = count
  }
  @Mutation
  public setTableDataCount(count: number) {
    this._tableDataCount = count
  }
  @Mutation
  public setTableCurPage(data: number) {
    this._tableCurPage = data
  }
  @Mutation
  public setTableHeight(height: number) {
    this._tableHeight = height
  }
  @Mutation
  public clearDataTablePageInfo() {
    this._tableDataCount = 0
    this._totalPages = 0
    this._tableCurPage = 0
  }

  /**
   * DataTable 相关
   */
  private _tb_selectColumns: IColumn[] = [] // table 选中列
  private _tb_selectRowNumbers: number[] = [] // table 选中行号
  private _tb_selectRowDatas: any[] = [] // table 选中行的数据
  private _tb_selectCellDatas: Array<CellInfo> = [] // table 选中的单元格
  private _tb_selectionType: SelectionType = SelectionType.none // table 当前表格选择模式
  private _tb_vue_instance: TableVueInstance | null = null
  private _tb_selectionInfo: SelectionInfo | null = null
  public get dataTableInstance() {
    return this._tb_vue_instance
  }
  public get tableSelectCells() {
    return this._tb_selectCellDatas
  }
  public get tableSelectColumns() {
    return this._tb_selectColumns
  }
  public get tableSelectRowNumbers() {
    return this._tb_selectRowNumbers
  }
  public get tableSelectRowDatas() {
    return this._tb_selectRowDatas
  }
  public get tableSelectionType() {
    return this._tb_selectionType
  }
  public get tableSelectionInfo() {
    return this._tb_selectionInfo
  }

  /**
   * 清空表格选择信息
   */
  @Mutation
  public clearTableSelection() {
    if (this._tb_vue_instance) {
      this._tb_vue_instance.clearAllSelect()
    }
    this._tb_selectColumns = []
    this._tb_selectRowNumbers = []
    this._tb_selectRowDatas = []
    this._tb_selectCellDatas = []
    this._tb_selectionType = SelectionType.none
  }

  /**
   * 存储表格选择信息
   * @param selectionInfo
   */
  @Mutation
  public setTableSelectionInfo(selectionInfo: SelectionInfo | null) {
    this._tb_selectionInfo = selectionInfo
  }
  @Mutation
  public setDataTableInstance(instance: TableVueInstance) {
    if (instance && isFunction(instance.clearTableSlection)) {
      this._tb_vue_instance = instance
    }
  }

  /**
   * 存储表格选择的 列
   * @param columns
   */
  @Mutation
  public setTableSelectColumns(columns: IColumn[]) {
    this._tb_selectColumns = columns
  }

  /**
   * 切换表格选择的列 （选择多列）
   * @param column
   */
  @Mutation
  public toggleTableSelectColumn(column: IColumn) {
    const index = this._tb_selectColumns.findIndex(
      (columnItem) => columnItem.name === column.name
    )
    if (index > -1) {
      this._tb_selectColumns.splice(index, 1)
    } else {
      this._tb_selectColumns = [...this._tb_selectColumns, column]
    }
  }

  /**
   * 存储表格选择的行数据
   * @param data
   */
  @Mutation
  public setTableSelectRowDatas(data: any[]) {
    this._tb_selectRowDatas = data
  }

  /**
   * 存储表格选择的行号
   * @param rows
   */
  @Mutation
  public setTableSelectRowNumbers(rows: number[]) {
    this._tb_selectRowNumbers = rows
  }

  /**
   * toggle 表格选择的行号
   * @param rowIndex
   */
  @Mutation
  public toggleTableSelectRowNumber(rowIndex: number) {
    if (this._tb_selectRowNumbers.includes(rowIndex)) {
      this._tb_selectRowNumbers.splice(rowIndex, 1)
    } else {
      this._tb_selectRowNumbers.push(rowIndex)
    }
  }

  /**
   * 表格选择的数据 toggle
   * @param data
   */
  @Mutation
  public toggleTableSelectData(data: any) {
    let tag = false
    let dataindex = -1
    this._tb_selectRowDatas.forEach((dataItem, index) => {
      if (Compare(dataItem, data)) {
        tag = true
        dataindex = index
      }
    })
    if (tag) {
      this._tb_selectRowDatas.splice(dataindex, 1)
    } else {
      this._tb_selectRowDatas.push(data)
    }
  }

  /**
   * 选择的 单元格
   * @param cells
   */
  @Mutation
  public setTableSelectCells(cells: Array<CellInfo>) {
    this._tb_selectCellDatas = cells
  }

  /**
   * 切换的单元格
   * @param cell
   */
  @Mutation
  public toggleTableSelectCell(cell: CellInfo) {
    // 判断新的cell是否在同一列
    const isSameColumn = this._tb_selectCellDatas.every((item) => {
      return item.columnName === cell.columnName
    })
    if (!isSameColumn) {
      this._tb_selectCellDatas = [cell]
    } else {
      const index = this._tb_selectCellDatas.findIndex((cellItem) => {
        return (
          cellItem.rowIndex === cell.rowIndex &&
          cellItem.columnName === cell.columnName
        )
      })
      if (index > -1) {
        this._tb_selectCellDatas.splice(index, 1)
      } else {
        this._tb_selectCellDatas.push(cell)
      }
    }
  }
  @Mutation
  public setTableSelectionType(selectionType: SelectionType) {
    this._tb_selectionType = selectionType
  }

  /**
   * gis 获取表数据详情 暂无使用
   * @param parameters
   */
  @Action({ commit: 'setLayerTableData' })
  public async gisQueryTableData(parameters: any) {
    const response = await queryTableDetailApi({
      data: {
        curPage: 1,
        name: '_record_id_', // 如果没有字段，那就固定传 _record_id_
        pageSize: 50,
        filter: [],
        ...parameters,
        taskId: -7,
      },
    })
    const result = response.data.result || {}
    return {
      head: result.head || [],
      data: result.data || [],
    }
  }

  // 列操作相关
  private _columnFilters: any[] = [] // 列字段上的筛选条件
  private _selectedColumns: any = [] // 选择的列
  public get selectedColumns() {
    return this._selectedColumns
  }
  public get columnFilters() {
    return this._columnFilters
  }
  @Mutation
  public setSelectedColumns(selectedColumn: IColumn[]) {
    this._selectedColumns = selectedColumn
  }
  @Mutation
  public toggleSelectedColumn(column: IColumn) {
    const columns = cloneDeep(this._selectedColumns)
    const index = columns.findIndex((item: any) => item.name === column.name)
    if (index !== -1) {
      columns.splice(index, 1)
    } else {
      columns.push(column)
    }
    this._selectedColumns = columns
  }
  @Mutation
  public clearSelectedColumns() {
    if (this._selectedColumns.length > 0) {
      this._selectedColumns = []
    }
  }
  @Mutation
  public setColumnFilters(filters: any[]) {
    this._columnFilters = filters
  }
  /**
   * 图层数据详情相关 -------- end --------
   */

  /**
   * 属性标记相关 -------- start --------
   */

  // 当前图层的 属性标记
  private _attributeTag: any[] = [] // 添加到标记的属性列表
  private _globalInfo: any = {} // 全局标记信息
  public get attributeTag() {
    return this._attributeTag
  }
  public get globalInfo() {
    return this._globalInfo
  }
  @Mutation
  public setCurrentLayerTagInfo(tagInfo: any) {
    this._attributeTag = tagInfo.attributeTag
    this._globalInfo = tagInfo.globalInfo
  }
  /**
   * 添加属性标记
   * @param attributeTagInfo 属性
   */
  @Mutation
  public addAttributeTag(attributeTagInfo: any) {
    this._attributeTag.push(attributeTagInfo)
  }
  @Mutation
  public deleteAttributeTag(index: number) {
    this._attributeTag.splice(index, 1)
  }
  @Mutation
  public editAttributeTag({
    index,
    tagType,
  }: {
    index: number
    tagType: string
  }) {
    this._attributeTag[index].tagType = tagType
  }
  // 修改当前图层的全局标记
  @Mutation
  public editTagInfoGlobalInfo(globalInfo: any) {
    Object.keys(globalInfo).forEach((key) => {
      if (
        Object.prototype.toString.call(globalInfo[key]) === '[object Object]'
      ) {
        this._globalInfo[key] = {
          ...this._globalInfo[key],
          ...globalInfo[key],
        }
      } else {
        this._globalInfo[key] = globalInfo[key]
      }
    })
  }
  // 修改当前图层的属性标记值
  @Mutation
  public editTagInfoAttributeTagValue({ index, config }: any) {
    this._attributeTag[index].config = config
  }

  // 图层属性（对应表字段）属性模块使用
  private _attributeFieldForLayer: any[] = []
  public get attributeFieldForLayer() {
    return this._attributeFieldForLayer
  }
  @Mutation
  public setAttributeFieldForLayer(attributes: any) {
    this._attributeFieldForLayer = attributes
  }
  /**
   * 根据表名获取图层数据表列（属性）
   * @param tableName
   */
  @Action
  public async gisQueryTableColumns(tableName: string) {
    const response = await queryTableDetailApi({
      data: {
        curPage: 1,
        name: '_record_id_', // 如果没有字段，那就固定传 _record_id_
        pageSize: 10,
        filter: [],
        table: tableName,
        taskId: -7,
      },
    })
    this.context.commit('setAttributeFieldForLayer', response.data.result.head)
    return response
  }

  // 图层属性值统计值（对应表字段值统计） 标记模块使用
  private _layerAttributeFieldStatistic: { [key: string]: any } = {}
  public get layerAttributeFieldStatistic() {
    return this._layerAttributeFieldStatistic
  }
  // 连续型
  @Mutation
  public setLayerAttributeFieldStatisticOfSuccessive(attributes: any) {
    this._layerAttributeFieldStatistic = {
      ...this._layerAttributeFieldStatistic,
      ...attributes,
    }
  }
  // 离散型
  @Mutation
  public setLayerAttributeFieldStatisticOfDiscrete(attributes: any) {
    const attributeName: string = Object.keys(attributes)[0]
    const attributeValue: any = attributes[attributeName]
    // 如果已存在
    if (this._layerAttributeFieldStatistic[attributeName]) {
      this._layerAttributeFieldStatistic[attributeName] = [
        ...this._layerAttributeFieldStatistic[attributeName],
        ...attributeValue,
      ]
      // 不存在
    } else {
      this._layerAttributeFieldStatistic[attributeName] = attributeValue
    }
  }
  @Mutation
  public clearLayerAttributeFieldStatistic() {
    this._layerAttributeFieldStatistic = {}
  }

  private _currentTabIsSync: boolean = false // 当前画布是否同步成功过系统构建
  public get currentTabIsSync() {
    return this._currentTabIsSync
  }

  @Mutation
  public setCurrentTabIsSync(status: boolean) {
    this._currentTabIsSync = status
  }

  /**
   * 获取图层数据表某列统计数据
   * @param parameters
   */
  @Action
  public async gisQueryTableColumnData(parameters: any) {
    const { name, table, curPage, desc } = parameters
    const response = await queryQueryStatApi({
      data: {
        data: {},
        filter: [],
        pageSize: 100,
        sortType: 1,
        sortVal: 'ASC',
        taskId: -7,
        type: 2,
        mode: 2,
        name,
        table,
        curPage,
      },
    })
    if (['decimal', 'int'].includes(desc)) {
      const { min, max } = response.data.result
      this.context.commit('setLayerAttributeFieldStatisticOfSuccessive', {
        [name]: [min, max],
      })
    } else {
      const { data } = response.data.result.pageCount
      const attributeValues: string[] = []
      data.forEach((item: any) => {
        if (item.column) {
          attributeValues.push(item.column)
        }
      })
      this.context.commit('setLayerAttributeFieldStatisticOfDiscrete', {
        [name]: attributeValues,
      })
    }
    return response
  }

  /**
   * 保存tab配置和图层配置
   */
  @Action
  public async gisSaveTabInfoWithLayer() {
    const parameters: any = {
      tabId: this._currentTabId,
      layers: this._layerList,
      tabInfo: this._gisTabs.find(
        (tab: any) => tab.tabId === this._currentTabId
      )?.data || {
        layerType: 1,
        legend: false,
        lnglat: true,
        mapType: 1,
        scale: true,
      },
    }
    const response: any = await saveInfoApi({ data: parameters })
    return response
  }

  /**
   * 同步画布内容至系统构建
   */
  @Action
  public async synchronousTab(imgUrl: string) {
    const parameters: any = {
      tid: this._currentTabId,
      projectId: this._projectId,
      name: this._gisTabs.filter((tab) => tab.tabId === this.currentTabId)[0]
        ?.tabName,
      type: 'gis',
      data: {
        thumbnail: imgUrl,
      },
    }
    const response: any = await synchronousTabApi({ data: parameters })
    return response
  }

  /**
   * 查询是否同步至系统构建
   */
  @Action({ commit: 'setCurrentTabIsSync' })
  public async querySynchronouTabStatus() {
    if (!this._currentTabId) {
      return true
    }
    const parameters: any = {
      tid: this._currentTabId,
    }
    const response: any = await querySynchronousStatus({ data: parameters })
    if (response.data.code === 100) {
      return response.data.result
    }
    return false
  }
}

export default getModule(GisStore)
